package com.airbnb.lottie.parser;

import android.graphics.Path;

import com.airbnb.lottie.LottieComposition;
import com.airbnb.lottie.model.animatable.AnimatableGradientColorValue;
import com.airbnb.lottie.model.animatable.AnimatableIntegerValue;
import com.airbnb.lottie.model.animatable.AnimatablePointValue;
import com.airbnb.lottie.model.content.GradientFill;
import com.airbnb.lottie.model.content.GradientType;
import com.airbnb.lottie.parser.moshi.JsonReader;
import com.airbnb.lottie.value.Keyframe;

import java.io.IOException;
import java.util.Collections;

class GradientFillParser {
    private static final JsonReader.Options NAMES = JsonReader.Options.of(
            "nm",
            "g",
            "o",
            "t",
            "s",
            "e",
            "r",
            "hd"
            , "pty"
    );
    private static final JsonReader.Options GRADIENT_NAMES = JsonReader.Options.of(
            "p",
            "k"
    );

    private GradientFillParser() {
    }

    static GradientFill parse(
            JsonReader reader, LottieComposition composition) throws IOException {
        String name = null;
        AnimatableGradientColorValue color = null;
        AnimatableIntegerValue opacity = null;
        GradientType gradientType = null;
        AnimatablePointValue startPoint = null;
        AnimatablePointValue endPoint = null;
        Path.FillType fillType = Path.FillType.WINDING;
        boolean hidden = false;
        int pty = 0;
        while (reader.hasNext()) {
            switch (reader.selectName(NAMES)) {
                case 0:
                    name = reader.nextString();
                    break;
                case 1:
                    int points = -1;
                    reader.beginObject();
                    while (reader.hasNext()) {
                        switch (reader.selectName(GRADIENT_NAMES)) {
                            case 0:
                                points = reader.nextInt();
                                break;
                            case 1:
                                color = AnimatableValueParser.parseGradientColor(reader, composition, points);
                                break;
                            default:
                                reader.skipName();
                                reader.skipValue();
                        }
                    }
                    reader.endObject();
                    break;
                case 2:
                    opacity = AnimatableValueParser.parseInteger(reader, composition);
                    break;
                case 3:
                    gradientType = reader.nextInt() == 1 ? GradientType.LINEAR : GradientType.RADIAL;
                    break;
                case 4:
                    startPoint = AnimatableValueParser.parsePoint(reader, composition);
                    break;
                case 5:
                    endPoint = AnimatableValueParser.parsePoint(reader, composition);
                    break;
                case 6:
                    fillType = reader.nextInt() == 1 ? Path.FillType.WINDING : Path.FillType.EVEN_ODD;
                    break;
                case 7:
                    hidden = reader.nextBoolean();
                    break;
                case 8:
                    pty = reader.nextInt();
                    break;
                default:
                    reader.skipName();
                    reader.skipValue();
            }
        }

        // Telegram sometimes omits opacity.
        // https://github.com/airbnb/lottie-android/issues/1600
        opacity = opacity == null ? new AnimatableIntegerValue(Collections.singletonList(new Keyframe<>(100))) : opacity;
        GradientFill gradientFill = new GradientFill(
                name, gradientType, fillType, color, opacity, startPoint, endPoint, null, null, hidden);
        gradientFill.setPty(pty);
        return gradientFill;
    }
}
